/*
 * $Id: BaseTransaction.java,v 1.7 2011/10/30 15:32:35 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.iptds.transaction;

import java.io.File;
import java.util.Date;

import org.springframework.util.Assert;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.database.dao.ICodeDetailsDAO;
import com.ge.healthcare.autosc.common.database.dao.IFileTransferDetailsDAO;
import com.ge.healthcare.autosc.common.database.dao.IRequestDAO;
import com.ge.healthcare.autosc.common.database.dao.IRequestListDAO;
import com.ge.healthcare.autosc.common.database.dao.ITaskDAO;
import com.ge.healthcare.autosc.common.database.dao.ITaskTypeDAO;
import com.ge.healthcare.autosc.common.database.pojo.ActFileTransferDetails;
import com.ge.healthcare.autosc.common.database.pojo.ActRequest;
import com.ge.healthcare.autosc.common.database.pojo.ActRequestList;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.database.pojo.CfgRequestDefn;
import com.ge.healthcare.autosc.common.database.pojo.CfgTaskType;
import com.ge.healthcare.autosc.common.dbLogger.StepLogger;
import com.ge.healthcare.autosc.common.util.CheckSumUtil;
import com.ge.healthcare.autosc.common.util.RequestDefnLookup;
import com.ge.healthcare.autosc.common.util.TimeFormatStandard;
import com.ge.healthcare.autosc.processor.IPTDSCodeConstants;
import com.ge.healthcare.autosc.processor.iptds.IPTDSSystemInfo;

/**
 * 
 * @author 212042946
 * 
 */
public class BaseTransaction {

	protected IRequestListDAO requestListDAO = null;
	protected IRequestDAO requestDAO = null;
	protected ITaskDAO taskDAO = null;
	protected ICodeDetailsDAO codeDetailsDAO = null;
	protected ITaskTypeDAO taskTypeDAO = null;
	protected IFileTransferDetailsDAO fileTransferDetailsDAO = null;
	protected ThreadLocal<String> exitCode = new ThreadLocal<String>();

	/**
	 * Init method. In spring framework, it is used as customized init method
	 */
	public void init() {
		Assert.notNull(requestListDAO,
				"ActRequestListDAO object is not defined. "
						+ "Please use setActRequestListDAO to provide one");
		Assert.notNull(requestDAO, "ActRequestDAO object is not defined. "
				+ "Please use setActRequestDAO to provide one");
		Assert.notNull(taskDAO, "ActTaskDAO object is not defined. "
				+ "Please use setActTaskDAO to provide one");
		Assert.notNull(taskTypeDAO, "TaskTypeDAO object is not defined. "
				+ "Please use setTaskTypeDAO to provide one");
		Assert.notNull(codeDetailsDAO, "codeDetailsDAO object is not defined. "
				+ "Please use setCodeDetailsDAO to provide one");
		Assert.notNull(fileTransferDetailsDAO,
				"fileTransferDetailsDAO object is not defined. "
						+ "Please use setFileTransferDetailsDAO to provide one");
	}

	public void setActRequestListDAO(IRequestListDAO requestListDAO) {
		this.requestListDAO = requestListDAO;
	}

	public void setActRequestDAO(IRequestDAO requestDAO) {
		this.requestDAO = requestDAO;
	}

	public void setActTaskDAO(ITaskDAO taskDAO) {
		this.taskDAO = taskDAO;
	}

	public void setCodeDetailsDAO(ICodeDetailsDAO codeDetailsDAO) {
		this.codeDetailsDAO = codeDetailsDAO;
	}

	public void setTaskTypeDAO(ITaskTypeDAO taskTypeDAO) {
		this.taskTypeDAO = taskTypeDAO;
	}

	public void setActFileTransferDetailsDAO(
			IFileTransferDetailsDAO fileTransferDetailsDAO) {
		this.fileTransferDetailsDAO = fileTransferDetailsDAO;
	}

	protected ActRequest createRequest(String requestType, String serviceId,
			String createdBy, ActRequestList requestList,
			IPTDSSystemInfo systemInfo) {
		String errorStr = null;

		ActRequest request = new ActRequest(systemInfo);
		request.setRequestListId(requestList.getRequestListId());
		// All valid systems should deserve to create valid request
		request.setRequestCode(codeDetailsDAO, IPTDSCodeConstants.TDS_S_REQ_000);
		CfgRequestDefn requestDefn = RequestDefnLookup.lookup(requestType,
				request.getModality(), request.getModelType(), serviceId,
				createdBy);
		if (requestDefn != null) {
			StepLogger.addStepLog("IPTDS request is created in valid status");
			request.setRequestDefn(requestDefn);
			request.setRequestDefnId(requestDefn.getRequestDefnId());
			requestList.addValidCount(1);
		} else {
			/*
			 * If we cannot find a valid request definition, AutoSC marks the
			 * request as invalid and would not create any task against it.
			 */
			errorStr = new StringBuffer()
					.append("Cannot find request definition.\n")
					.append("{requestType: IPTDS").append("},")
					.append("{modality: ").append(systemInfo.getModality())
					.append("},").append("{modelType: ")
					.append(systemInfo.getModelType()).append("}").toString();
			ASCLogger.error(this.getClass(), "createRequest", errorStr, true);
			request.setRequestCode(codeDetailsDAO,
					IPTDSCodeConstants.TDS_F_REQ_000);
			requestList.addInvalidCount(1);
		}
		requestDAO.save(request);
		// update the valid count
		requestListDAO.save(requestList);
		requestList.addRequest(request);
		ASCLogger
				.debug(this.getClass(), "createRequest", "request: " + request);
		return request;
	}

	protected ActTask createTask(ActRequest request) {
		ActTask task = null;
		if (isRequestValid(request)) {
			task = new ActTask();
			task.setRequestId(request.getRequestId());
			task.setFailedCount(new Long("0"));
			task.setStepTypeId(StepLogger.getStepTypeId());
			task.setTaskType(getTaskTypeName(request.getRequestDefn()));
			task.setInternalAutoSC();
			task.setPriority(new Long("1"));
			task.setExpireDate();
			task.setTaskCode(codeDetailsDAO, exitCode.get());
			task.setStartTime();
			task.setEndTime();
			taskDAO.save(task);
			ASCLogger.debug(this.getClass(), "createTask", "Task: " + task);
			request.addActTask(task);
		}
		return task;
	}

	protected void createFileTransferDetails(Long requestId, File file,
			Date startDate, Date endDate, boolean status, boolean internal) {
		String methodName = "createFileTransferDetails";
		ActFileTransferDetails ftDetails = new ActFileTransferDetails();
		ftDetails.setRequestId(requestId);
		ftDetails.setGetDirection();
		ftDetails.setContentSize(file.length());
		ftDetails.setFileName(file.getName());
		ftDetails.setInternalCommFile(internal);
		ftDetails.setFileDir(file.getParent());
		ftDetails.setStartTime(startDate);
		ftDetails.setEndTime(TimeFormatStandard.getNowMillis());
		if (status == true) {
			ftDetails.setCompleted();
			try {
				ftDetails.setCheckSum(CheckSumUtil.getMD5Checksum(file
						.getAbsolutePath()));
			} catch (Exception e) {
				String errorStr = "Failed create checksum for file "
						+ file.getAbsolutePath();
				ASCLogger.error(this.getClass(), methodName, errorStr, e);
				// throw new BasicRuntimeException(errorStr, e,
				// IPTDSCodeConstants.PRC_F_TDS_017);
			}
		} else {
			ftDetails.setFail();
		}
		fileTransferDetailsDAO.save(ftDetails);

	}

	protected boolean isRequestValid(ActRequest request) {
		boolean valid = false;
		if (request.getCodeName() != null) {
			if (request.getCodeName().equals(IPTDSCodeConstants.TDS_S_REQ_000)) {
				valid = true;
			}
		}
		return valid;
	}

	private String getTaskTypeName(CfgRequestDefn requestDefn) {
		String taskTypeName = null;
		if (requestDefn != null) {
			CfgTaskType taskType = taskTypeDAO.getByID(requestDefn
					.getInitialTaskId());
			if (taskType != null) {
				taskTypeName = taskType.getTaskTypeName();
			}
		}
		return taskTypeName;
	}
}
